package pers.xx.sbm.utils.file;

import freemarker.template.utility.StringUtil;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author ：xiexing
 * @description：文件差分
 * @date ：2020/9/5 20:40
 */
public class FileSpiltUtils {


    public static void main(String[] args) {
        String filePath = "C:\\Users\\18359\\Desktop\\test_log\\catalina_243_2020-06-19\\谢兴_20037_18242097519_243.out";
        int blockFileSize = 1024 * 1024 * 2;// 2M
        try{
            splitBySize(filePath,blockFileSize);
        }catch (IOException e){
            System.out.println("文件差分出错");
        }

    }

    /**
     * 拆分文件
     *
     * @param fileName 待拆分的完整文件名
     * @param byteSize 按多少字节大小拆分
     * @return 拆分后的文件名列表
     * @throws IOException
     */
    public static List<String> splitBySize(String fileName, int byteSize)
            throws IOException {
        List<String> parts = new ArrayList<String>();
        File file = new File(fileName);
        System.out.println(file.length());
        int count = (int) Math.ceil(file.length() / (double) byteSize);
        System.out.println("拆分的文件个数"+count);
        int countLen = (count + "").length();
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(count,
                count * 3, 1, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(count * 2));
        long startPos = 0L;
        for (int i = 0; i < count; i++) {
            String partFileName = file.getName() + "."
                    + StringUtil.leftPad((i + 1) + "", countLen, '0') + ".part";
            startPos = (long)byteSize * (long)i;
            threadPool.execute(new SplitRunnable(byteSize, startPos,
                    partFileName, file));
            parts.add(partFileName);
        }
        return parts;
    }
}

class SplitRunnable implements Runnable {
    int byteSize;
    String partFileName;
    File originFile;
    long startPos;

    public SplitRunnable(int byteSize, long startPos, String partFileName,
                         File originFile) {
        this.startPos = startPos;
        this.byteSize = byteSize;
        this.partFileName = partFileName;
        this.originFile = originFile;
    }

    public void run() {
        RandomAccessFile rFile;
        OutputStream os;
        try {
            rFile = new RandomAccessFile(originFile, "r");
            byte[] b = new byte[byteSize];
            rFile.seek(startPos);// 移动指针到每“段”开头
            int s = rFile.read(b);
            os = new FileOutputStream("C:\\Users\\18359\\Desktop\\test_log\\catalina_243_2020-06-19\\dest\\"+partFileName);
            os.write(b, 0, s);
            b=null;
            os.flush();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
